#coding=utf-8
'''
Created on 2017-04-26

@author: sandy
'''

from twisted.internet import task
import logging
from pycommon import Const,DbPool,Utils
from pycommon import Pack as packet
import UserManager
import FirstLoginConfig


class GameDB(object):
    def __init__(self):
        self.__linkcount = 0
        self.__dbp = None
        self.lastFinishOrderId = 0

    def start(self,db,user,passwd,host=u'127.0.0.1',port=3306,linkcount=3):
        logging.info("gamedb host=%s db=%s user=%s",host,db,user)
        l = task.LoopingCall(self.onTimer)
        l.start(1, False)
        self.__linkcount = linkcount
        self.__dbp = DbPool.DBConnectionPool(db = db,user = user,passwd = passwd,host = host,port = port,linkcount = linkcount)
        self.__dbp.start()

    def stop(self):
        self.__dbp.stop()
        
    def onTimer(self):
        self.doTask()

    
    def doTask(self):
        self.finishOrder()
        pass
            
    def hashIndex(self, uid):
        return uid % self.__linkcount
    
    def hashIndexAccount(self, account):
        return ord(account[0]) % self.__linkcount  
    
    def query(self, conindex, ctx, sql, params, func):
        self.__dbp.query(conindex, ctx, sql, params, func)

    def execute(self, conindex, ctx, sql, params, func):
        self.__dbp.execute(conindex, ctx, sql, params, func)

    def call(self, conindex, ctx, proc, params, func):
        self.__dbp.call(conindex, ctx, proc, params, func)

    def login(self, client, account, passwd):
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_login(%s, %s)"
        params = (account, passwdsign)
        ctx = (client, account, passwd)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.loginResult)

    def loginResult(self, ctx, error, rows):
        client, account, passwd = ctx

    def register(self, client, account, passwd):
        passwdsign = Utils.passwdHash(account, passwd)
        sql = u"call p_aa_register(%s, %s)"
        params = (account, passwdsign)
        ctx = (client, account, passwd)
        self.query(self.hashIndexAccount(account),ctx,sql,params,self.registerResult)

    def registerResult(self, ctx, error, rows):
        client, account, passwd = ctx
        #print ctx

    #CountManager统计数据
    def saveCounter(self, counter, count):
        sql = u"call p_save_counter(%s,%s)"
        params = (counter, count)
        ctx = (counter, count)
        self.query(self.hashIndex(counter),ctx,sql,params,self.saveCounterResult)
        
    def saveCounterResult(self, ctx, error, rows):
        counter, count = ctx
        if error:
            logging.error(u"saveCounterResult() counter=%d, count=%d error=%s",counter,count,str(error))
        else:
            logging.info(u"saveCounterResult() counter=%d, count=%d sucess",counter,count)

    
    def userFirstLogin(self,uid,propId,propCount,propertyId,propertyCount):
        sql = u"call p_user_first_login(%s,%s,%s,%s,%s)"
        params = (uid,propId,propCount,propertyId,propertyCount)
        ctx = (uid,propId,propCount,propertyId,propertyCount)
        self.query(self.hashIndex(uid),ctx,sql,params,self.userFirstLoginResult)
        pass

    def userFirstLoginResult(self, ctx, error, sets):
        logging.debug("userFirstLoginResult")
        uid,propId,propCount,propertyId,propertyCount = ctx
        if error:
            logging.error(u"userFirstLoginResult() uid=%d, err=%s", uid, error)
            return
        self.loadUserInfo(uid)
        pass

    #玩家上线 加载玩家数据
    def loadUserInfo(self,uid):
        logging.debug(u"uid = %d loadUserInfo",uid)
        #加载玩家prop property等信息
        proc = u"p_load_user_info"
        params = (uid,)
        ctx = uid
        self.call(self.hashIndex(uid), ctx, proc, params, self.loadUserInfoResult)
        pass

    def loadUserInfoResult(self, ctx, error, sets):
        logging.debug(u"loadUserInfoResult")
        uid = ctx
        if error:
            logging.error(u"loadUserMoneyResult() uid=%d, err=%s", uid, error)
            return
        logging.info(u"loadUserInfoResult() sets=%s", str(sets))
        if len(sets[0]) == 0:
            logging.debug("the first login")
            propId = FirstLoginConfig.instance.getPropId()
            propCount = FirstLoginConfig.instance.getPropCount()
            propertyId = FirstLoginConfig.instance.getPropertyId()
            propertyCount = FirstLoginConfig.instance.getPropertyCount()
            self.userFirstLogin(uid,propId,propCount,propertyId,propertyCount)
        else:
            logging.debug("not the first login")
            user = UserManager.instance.getUser(uid)
            user.loadProp(sets[0])
            user.loadProperty(sets[1])
            user.loadUserInfoFinished()
        pass

    def finishOrder(self):
        sql = u"call p_order_get_state(%s)"
        params = (Const.ORDER_STATE_PAYSUCESS,)
        ctx = None
        self.query(self.hashIndex(self.lastFinishOrderId),ctx,sql,params,self.finishOrderResult)
    
    def finishOrderResult(self, ctx, error, rows): 
        if error:
            logging.error(u"finishOrderResult() self.lastFinishOrderId=%d, err=%s",self.lastFinishOrderId,str(error))
            return
        ret = int(rows[0][0])
        orderid = int(rows[0][1])
        paytype = int(rows[0][2])
        if ret == Const.ERR_OK and orderid > 0 and paytype > 0:
            self.lastFinishOrderId = orderid
            self.orderPaySuc(orderid, paytype)
    

    def orderPaySuc(self,orderid, paytype):
        sql = u"call p_order_pay_suc(%s,%s)"
        params = (orderid, paytype)
        ctx = (orderid, paytype)
        self.query(self.hashIndex(orderid),ctx,sql,params,self.orderPaySucResult)

    def orderPaySucResult(self, ctx, error, rows):
        orderid, paytype = ctx
        if error:
            logging.error(u"orderPaySucResult(), orderid=%d, paytype=%d, err=%s",orderid,paytype,str(error))
            return
        ret = int(rows[0][0])
        uid = int(rows[0][1])
        valueitems = rows[0][2]
        state = int(rows[0][3])  
        money = int(float(rows[0][4])) 
        tradeid = int(rows[0][5])     
        tradename = rows[0][6]  
        cv = int(rows[0][7])
        cvpoolvalue = int(rows[0][8]) 
        if ret != Const.ERR_OK:
            logging.info(u"orderPaySucResult()Fail,ret=%d,orderid=%d,paytype=%d,uid=%d valueitems=%s",ret,orderid,paytype,uid,valueitems)
        else:
            logging.info(u"orderPaySucResult()SUC,orderid=%d,paytype=%d,uid=%d valueitems=%s",orderid,paytype,uid,valueitems)
            self.onOrderPaySuc(orderid, money, valueitems, paytype, uid, tradeid, tradename, cv, cvpoolvalue)

    def onOrderPaySuc(self, orderid, money, valueitems, paytype, uid, tradeid, tradename, cv, cvpoolvalue):
        payuser = UserManager.instance.getUser(uid)
        if payuser:
            payuser.chargeSucess(valueitems,Const.PROP_CHANGE_CHAGE)


    def updateProp(self,uid,propId,propCount,way):
        sql = u"call p_prop_update(%s,%s,%s,%s)"
        params =(uid,propId,propCount,way)
        ctx=(uid,propId,propCount,way)
        self.query(self.hashIndex(uid),ctx,sql,params,self.updatePropResult)

    def updatePropResult(self,ctx,error,rows):
        uid,propId,propCount,way = ctx
        logging.debug("updatePropResult uid=%d pid=%d num=%d way=%d",uid,propId,propCount,way)
        if error:
            logging.error(u"updatePropResult() uid=%d error=%s",uid,str(error))
            return
        if int(rows[0][0]) != Const.ERR_OK:
            logging.debug(u"updatePropResult() uid=%d errorcode=%s",uid,int(rows[0][0]))
            return
        logging.debug("uid=%d propId=%d propCount=%d way=%d updatePropResult Sucess",uid,propId,propCount,way)
        user = UserManager.instance.getUser(uid)
        if user:
            if way == Const.PROP_CHANGE_BACK:
                user.addProp(abs(propCount))
            user.sendPropToClient()
        else:
            logging.debug("updatePropResult uid=%d notExit",uid)


    

instance = GameDB()

if __name__ == '__main__':
    pass